﻿Imports System.IO
Imports System.Windows.Forms
Imports System.Drawing
Imports System.Text.RegularExpressions
Imports System.Collections.Generic

Public Class CustomLists

#Region "Globals"

    'public
    Public PluginAppDir As String = (Application.StartupPath() & "\PLUGINS\CustomLists")
    Public XMLFile As String = (Application.StartupPath() & "\PLUGINS\CustomLists\Data.xml")
    Public SettingsIni As String = (Application.StartupPath() & "\PLUGINS\CustomLists\Settings.ini")
    Public _log As New Logger
    Public _status As New StatusWindow
    Public _GEdata As New DataTable
    Public _GEdataDV As New DataView
    Public _DBOps As New DBOps
    Public myset As New MySetts

    Public _ParentDV As New DataView
    Public _ListsDV As New DataView

    Public _ListsBS As New BindingSource
    Public _ListNodeBS As New BindingSource
    Public ListNodesDV As New DataView

    Public formshown As Boolean = False
    Public GEThemePath As String = Nothing

    Public IconsPath As String

    Public SWorking As New DataTable ' used in CustmMenus.ini production

    Public test As DataTable

    Public CustMenuSecs As New Dictionary(Of String, String)
    Public URLPairs As New Dictionary(Of String, Integer)

#End Region

    Private Sub CustomLists_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing

        _log.echo("Form Closing.. bye.")

        'Write changelog
        File.WriteAllText((Application.StartupPath() & "\PLUGINS\CustomLists\Changelog.txt"),
                           My.Resources.ChangeLog)

        'Save Def root folder
        My.Settings.MenuRoot = RootCB.Text


        'SAVE WINDOW POSs
        'Main
        My.Settings.EditorPos = Me.Location
        My.Settings.EditorSize = Me.Size
        My.Settings.EditorWinState = Me.WindowState

        'Debug Window
        My.Settings.DebugSize = _status.Size
        My.Settings.DebugPos = _status.Location
        My.Settings.DebugWinState = _status.WindowState

        My.Settings.Save()

        Me.Validate()
        ListBindingSource.EndEdit()
        CListDS.WriteXml(XMLFile)

        myset.IniPath = SettingsIni
        myset.SaveSetts()

        _DBOps.SaveGEDb3(_GEdata)

        _status.Close()


    End Sub

    Private Sub InitialFormShown() Handles Me.Shown

        If Not (IsOnScreen(Me)) Then
            Me.Location = New System.Drawing.Point(10, 10)
        End If

        If Me.Size.Height < 400 Or Me.Size.Width < 400 Then
            Me.Size = New Size(600, 400)
        End If
        ' END intial layout
        'Me.Size = New Size(600, 400)
        _log.echo("Form shown.")

    End Sub

    Private Sub CustomLists_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        Me.Text = GameEx.PluginInfo.Name & " - " & GameEx.PluginInfo.Version

        'Initial layout
        Me.Font = My.Settings.EditorFont
        Me.Location = My.Settings.EditorPos
        Me.Size = My.Settings.EditorSize
        Me.WindowState = My.Settings.EditorWinState

        SetupForm()

    End Sub

    Public Function IsOnScreen(ByVal form As Form) As Boolean
        Dim screens() As Screen = Screen.AllScreens

        For Each scrn As Screen In screens
            Dim formRectangle As Rectangle = New Rectangle(form.Left, form.Top, form.Width, form.Height)

            If scrn.WorkingArea.Contains(formRectangle) Then
                Return True
            End If
        Next

        Return False
    End Function

    Public Sub Initialise()

        _status.echo("Initialising")

        'check plugin folder exists
        CheckPluginInstall()

        'Load Setts
        If File.Exists(SettingsIni) Then
            ' nuttin - s'all gud, man
        Else
            File.WriteAllText(SettingsIni, My.Resources.DefaultIni)
        End If
        myset.IniPath = SettingsIni
        myset.LoadSetts()

        'log
        If myset.KeepLog Then
            _log.Initialize(GameEx.PluginInfo.Name,
                           GameEx.PluginInfo.Version,
                           PluginAppDir & "\CustomLists.log",
                           myset.DebugLog)
            _log.echo("Starting Plugin Initialisation", "plugin started", "Initialise", "CustomLists")
            _log.echo("Log started: " & DateTime.Now.ToString("dd-MMMM-yy"))
            _log.echo("Staring Window:")
            _log.echo("Position: " & My.Settings.EditorPos.ToString)
            _log.echo("Size: " & My.Settings.EditorSize.ToString)
            _log.echo("Window: " & My.Settings.EditorWinState)
        End If

        'debug window
        If myset.ShowDebugWindow Then
            _status.Show()
            _status.Location = My.Settings.DebugPos
            _status.Size = My.Settings.DebugSize

            If Not (IsOnScreen(_status)) Then
                _status.Location = New System.Drawing.Point(10, 10)
            End If

            If _status.Size.Height < 400 Or _status.Size.Width < 400 Then
                _status.Size = New Size(600, 400)
            End If

            If myset.DebugToLog = True Then
                _status.DebugToLog = True
                _status.LogToUse = _log
            End If

        End If

        'get GE Theme path
        _log.echo("Get GE Theme path.")
        If GameExThemeMediaPath() = False Then
            _log.err("Error loading theme path")
        Else
            _log.echo("Grab success: " & GEThemePath)
        End If

        _log.echo("Checking Dependencies")
        'check dependencies in exitence
        Dim deps As New List(Of String) From {"/PLUGINS/LinqBridge.dll", "/PLUGINS/SQLite.Interop.dll", "/PLUGINS/System.Data.SQLite.dll"}
        For Each dep As String In deps
            If File.Exists(Application.StartupPath & dep) Then
                _log.echo("Exists: " & dep)
            Else
                _log.err("MISSING: " & dep)
            End If
        Next

        'load/create xml
        If My.Computer.FileSystem.FileExists(XMLFile) Then
            CListDS.ReadXml(XMLFile)
        Else
            _log.echo("XML doesn't exist.")
            'CListDS.WriteXml(XMLFile)
        End If

        _status.echo("Checking Root in Lists")
        Dim nrow() As DataRow = CListDS.Tables("List").Select("ID = -1")
        If nrow.Length < 1 Then
            _status.echo("Not in lists - adding")
            Dim newrow As DataRow = CListDS.Tables("List").NewRow
            newrow.Item("ID") = -1
            newrow.Item("Name") = "Custom Lists"
            newrow.Item("ImagePath") = GEThemePath & "LOGOS\ListsMain.png"
            newrow.Item("URL") = "n/a"
            newrow.Item("OrderInList") = 0
            newrow.Item("ItemType") = "Folder"
            newrow.Item("Parent") = -1
            CListDS.Tables("List").Rows.Add(newrow)
        End If


        '----------- GAMEEX STUFF:  ----------------------------------------------------
        _log.echo("--------------------------------------------------------")
        _log.echo("", "Importing GameEx Data")

        'import GameEx data.db3
        _GEdata.TableName = "Data"
        Try
            _GEdata = _DBOps.ImportGEDb3(Application.StartupPath() & "\DATA\DATA.db3", "Data")
        Catch ex As Exception
            _log.err(ex.Message, "importing ge data")
        End Try

        Dim sellist As New Data.DataColumn("Select", Type.GetType("System.Boolean"))
        sellist.DefaultValue = False
        _GEdata.Columns.Add(sellist)
        sellist.Dispose()

        Dim onlist As New Data.DataColumn("OnList", Type.GetType("System.Boolean"))
        onlist.DefaultValue = False
        _GEdata.Columns.Add(onlist)
        onlist.Dispose()

        Dim gamename As New Data.DataColumn("GameName", Type.GetType("System.String"))
        gamename.DefaultValue = ""
        _GEdata.Columns.Add(gamename)
        gamename.Dispose()

        _log.echo("Finished User game database import.")
        ' _log.echo("Number of rows: " & CListDS.Tables("List").Rows.Count)

        'Import GE Emus
        CListDS.Merge(GEUserEmus(), False, MissingSchemaAction.Add)
        _log.echo("Importing User GameEx Emulators:")
        For Each row As DataRow In CListDS.Tables("UserEmulators").Rows
            _log.echo(row.Item("StartPageName") & ", " & row.Item("EmuNumber"))
            _status.echo(row.Item("StartPageName") & ", " & row.Item("EmuNumber"), True)
        Next
        _log.echo("--------------------------------------------------------")

        'check default images transferred to Tehem folder
        Dim DefImgs As New List(Of String) From {"ListFolder", "ListGames", "ListLoad", "ListsMain",
                                                 "ListView", "ListWWW"}
        IconsPath = GEThemePath & "LOGOS\"  ' IMPORTANT GLOBAL - DO NOT ERASE
        _log.echo("Checking Theme folder has needed images.")
        _log.echo("Folder: " & IconsPath)
        For Each filename As String In DefImgs
            If Not My.Computer.FileSystem.FileExists(IconsPath & filename & ".png") Then
                _log.echo("File does not exist. Using Defualt: " & IconsPath & filename & ".png")
                Select Case filename
                    Case "ListFolder"
                        My.Resources.ListFolder.Save(IconsPath & filename & ".png")
                    Case "ListGames"
                        My.Resources.ListGames.Save(IconsPath & filename & ".png")
                    Case "ListLoad"
                        My.Resources.ListLoad.Save(IconsPath & filename & ".png")
                    Case "ListsMain"
                        My.Resources.ListsMain.Save(IconsPath & filename & ".png")
                    Case "ListView"
                        My.Resources.ListView.Save(IconsPath & filename & ".png")
                    Case "ListWWW"
                        My.Resources.ListWWW.Save(IconsPath & filename & ".png")
                End Select
            Else
                _log.echo("Image already in Themes folder: " & filename)
            End If
        Next


        '------------ END GE IMPORTS =------------------------

        'Update any Status window stuff
        _status.DGV.DataSource = CListDS.Tables("UserEmulators")

        If myset.ShowWithGameEx = True Then
            Me.Show()
        End If

        'Populate Menus dictionary
        GetCMenus()
        ' and bind to combobox
        RootCB.DataSource = New BindingSource(CustMenuSecs, Nothing)
        RootCB.DisplayMember = "Key"
        RootCB.ValueMember = "Value"


        _log.echo("Initialisation Finished.")
        _log.echo("--------------------------------------------------------")

    End Sub

    Private Function GetCMenus() As Boolean

        _log.echo("Getting CustomMenus and corresponding titles")
        Dim GECMenuIni As New IniFile
        GECMenuIni.Load(Application.StartupPath() & "\CONFIG\CustomMenu.ini")
        For Each cmenusec As IniFile.IniSection In GECMenuIni.Sections
            If cmenusec.Name <> "[GENERAL]" And cmenusec.GetKey("TITLE") IsNot Nothing Then
                CustMenuSecs.Add(cmenusec.Name & ": " & NotNull(cmenusec.GetKey("TITLE").Value, "{No Title}"), cmenusec.Name)
                _log.echo("Added: " & cmenusec.Name & ": " & NotNull(cmenusec.GetKey("TITLE").Value, "{No Title}"))
            End If
        Next
    End Function

    Public Function GameExThemeMediaPath() As Boolean
        Try
            Dim GEini As New IniFile
            GEini.Load(Application.StartupPath() & "\CONFIG\GameEx.ini")
            GEThemePath = Application.StartupPath & GEini.GetKeyValue("CachedImages3d", "themedir")
        Catch ex As Exception
            _log.err("Error trying to get Theme path.")
            Return False
        End Try
        Return True
    End Function

    Private Sub SetupForm()


        _log.echo("--------------------------------------------------------")
        _log.echo("Form being setup.")
        'Checkboxes
        KeepLogChB.Checked = myset.KeepLog
        LogDebugChB.Checked = myset.DebugLog
        ShowCGEChB.Checked = myset.ShowWithGameEx
        ShowDebugWindowChB.Checked = myset.ShowDebugWindow
        Debug2LogChB.Checked = myset.DebugToLog


        'DropDowns
        With SysCB
            .DisplayMember = "StartPageName"
            .ValueMember = "EmuNumber"
            .DataSource = CListDS.Tables("UserEmulators")
        End With

        With GameCB
            .DisplayMember = "RomFile"
            .ValueMember = "RomFile"
            .DataSource = _GEdata
        End With


        _ParentDV = CListDS.Tables("List").DefaultView
        _ParentDV.RowFilter = "ItemType = 'Folder'"
        With ParentComboBox
            .DisplayMember = "Name"
            .ValueMember = "ID"
            .DataSource = New BindingSource(_ParentDV, Nothing)
        End With

        ListViewCB.SelectedIndex = 0


        _ListsBS.DataSource = New DataView(CListDS.Tables("List"))
        _ListsBS.Sort = "ItemType ASC, Name ASC"
 
        _ListNodeBS.DataSource = CListDS.Tables("List")
        _ListNodeBS.Filter = "ItemType = 'Folder'"
        With ListNodesCB
            .DisplayMember = "Name"
            .ValueMember = "ID"
            .DataSource = _ListNodeBS
        End With


        'URLDictionary pop
        URLPairs.Clear()
        URLPairs.Add("", -1)
        Dim GEIni As New IniFile
        Dim URLno As Integer
        GEIni.Load(Application.StartupPath() & "\CONFIG\GameEx.ini")
        For Each key As IniFile.IniSection.IniKey In GEIni.GetSection("htmlapplications").Keys
            _status.echo(".")
            _status.echo("Key, value: " & key.Name & ", " & key.Value)
            If (key.Name Like "enabled_*" Or key.Name Like "Enabled_*") And key.Value = "True" Then
                URLno = CInt(key.Name.Split("_")(1))
                _status.echo("URL no: " & URLno)
                URLPairs.Add(URLno & ": " & GEIni.GetSection("htmlapplications").GetKey("Name_" & URLno).Value,
                             URLno)
            End If
        Next
        'and dropdown:
        URLCB.DataSource = New BindingSource(URLPairs, Nothing)
        URLCB.DisplayMember = "Key"
        URLCB.ValueMember = "Value"

        'Setup main dgv
        _GEdataDV = _GEdata.DefaultView
        _GEdataDV.Sort = "RomFile ASC"
        SetupDGVs()

        _log.echo("Form Setup Finished.")
        _log.echo("--------------------------------------------------------")

        _status.echo("")
        For Each dcol As DataGridViewColumn In ListsDGV.Columns
            _status.echo("Name: " & dcol.Name)
        Next

        'Settings: Def IMages
        DefPic1.Image = SafeImageFromFile(IconsPath & "ListsMain.png")
        DefPic2.Image = SafeImageFromFile(IconsPath & "ListFolder.png")
        DefPic3.Image = SafeImageFromFile(IconsPath & "ListGames.png")
        DefPic4.Image = SafeImageFromFile(IconsPath & "ListLoad.png")
        DefPic5.Image = SafeImageFromFile(IconsPath & "ListView.png")
        DefPic6.Image = SafeImageFromFile(IconsPath & "ListWWW.png")

        'pop def menu root
        If CustMenuSecs.ContainsKey(My.Settings.MenuRoot) Then
            RootCB.Text = My.Settings.MenuRoot
        End If

        _status.echo("--------------------------")
        For Each pair As KeyValuePair(Of String, Integer) In URLPairs
            _status.echo(pair.Key & ": " & pair.Value)
        Next

        _status.echo("--------------------------")
        ' HANDLERS
        AddHandler CListDS.Tables("List").RowChanged, New DataRowChangeEventHandler(AddressOf ListDTRowChanged)
    End Sub

    Private Sub ListsImgUpdate()
        For Each drow As DataGridViewRow In ListsDGV.Rows
            If drow.Cells("ItemType").Value = "Folder" Then
                drow.Cells("PBCol").Value = My.Resources.Folder_icon
            ElseIf drow.Cells("ItemType").Value = "List" Then
                drow.Cells("PBCol").Value = My.Resources.list
            End If
        Next
    End Sub

    Private Sub SetupDGVs()

        With CListDGV
            .AutoSizeColumnsMode = Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells

            .Columns.Add(New DataGridViewComboBoxColumn With {.DataPropertyName = "EmuNumber", .Visible = True,
                                            .Name = "EmuNumber", .HeaderText = "GameEx Emulator",
                                            .DataSource = New BindingSource(CListDS.Tables("UserEmulators"), Nothing),
                                                .DisplayMember = "StartPageName",
                                                .ValueMember = "EmuNumber",
                                            .FlatStyle = FlatStyle.Flat,
                                            .AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells})

            .DataSource = _GEdataDV

            .Columns("Select").DisplayIndex = 0
            .Columns("OnList").DisplayIndex = 1
            .Columns("Select").SortMode = DataGridViewColumnSortMode.Automatic
            .Columns("OnList").SortMode = DataGridViewColumnSortMode.Automatic
            .Columns("EmuNumber").SortMode = DataGridViewColumnSortMode.Automatic
            .Columns("VIDEO_Position").Visible = False
            .Columns("VIDEO_Aspect").Visible = False
            .Columns("GameName").DisplayIndex = 4
            .Columns("MinutesPlayed").DefaultCellStyle.Format = "N0"

            If My.Settings.ShowFaves = True Then
                .Columns("Favorite").Visible = True
            Else
                .Columns("Favorite").Visible = False
            End If

        End With

        For Each col As DataGridViewColumn In CListDGV.Columns
            col.ReadOnly = True
            If col.HeaderText = "Select" Then
                col.DefaultCellStyle.ForeColor = SystemColors.ActiveCaptionText
            Else
                col.DefaultCellStyle.ForeColor = SystemColors.InactiveCaptionText
            End If
        Next
        CListDGV.Columns("Select").ReadOnly = False
        '   CListDGV.Columns("OnList").ReadOnly = False
        CListDGV.Columns("RomFile").AutoSizeMode = DataGridViewAutoSizeColumnMode.None

        'LISTS DGV
        With ListsDGV
            .AutoSizeColumnsMode = Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells

            .Columns.Add(New DataGridViewImageColumn With {.Name = "PBCol",
                                                           .ImageLayout = DataGridViewImageCellLayout.Zoom,
                                                           .HeaderText = "",
                                                           .SortMode = DataGridViewColumnSortMode.Programmatic})

            .DataSource = _ListsBS

            With .Columns("ID")
                .DisplayIndex = 5
                .Visible = False
            End With
            '.Columns("Name").Frozen = True

            .Columns("PBCol").DefaultCellStyle.Padding = New Padding(2, 2, 2, 2)
            .Columns("ImagePath").Visible = False
            .Columns("URL").Visible = False
            .Columns("Parent").Visible = False
            .Columns("Title").Visible = False
            .Columns("ItemType").Visible = False
            .Columns("OrderInList").HeaderText = "Order"
            .Columns("ItemType").ReadOnly = True


        End With

    End Sub

    Private Sub ListsDGV_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles ListsDGV.CellDoubleClick
        _status.echo(e.RowIndex & ", " & e.ColumnIndex)

        Dim drow() As DataRow

        If e.ColumnIndex = -1 And e.RowIndex = -1 Then
            drow = CListDS.Tables("List").Select("ID = " & ListsDGV.Rows(0).Cells("Parent").Value)
            _status.echo("Grandparent: " & drow(0).Item("Parent"))
            ListNodesCB.SelectedValue = drow(0).Item("Parent")
            Return
        End If

        If e.ColumnIndex < 0 Or e.RowIndex < 0 Then Return

        sender.Rows(e.RowIndex).Selected = True

        '   If ListsDGV.Columns(e.ColumnIndex).Name = "PBCol" Then
        drow = CListDS.Tables("List").Select("[Parent] = " & ListsDGV.Rows(e.RowIndex).Cells("ID").Value)
        If drow.Length > 0 Then
            ListNodesCB.SelectedValue = ListsDGV.Rows(e.RowIndex).Cells("ID").Value
        End If
        '  End If

    End Sub




    Public Function GEUserEmus() As DataTable
        Try

        Catch ex As Exception

        End Try
        Dim emudt As New DataTable
        emudt.TableName = "UserEmulators"
        emudt.Columns.Add("EmuNumber", GetType(Integer))
        emudt.Columns.Add("StartPageName", GetType(String))
        emudt.Columns.Add("TitleText", GetType(String))
        emudt.Columns.Add("Database", GetType(String))
        emudt.Columns.Add("SnapPath", GetType(String))
        emudt.Columns.Add("TitlePath", GetType(String))
        emudt.Columns.Add("Enabled", GetType(Boolean))
        emudt.Columns.Add("RomPath", GetType(String))

        Dim GEini As New IniFile
        GEini.Load(Application.StartupPath() & "\CONFIG\GameEx.ini")
        For Each Section As String In GEini.SectionList
            If Section.Contains("Emulator_") Then
                Dim EmuNumber As Integer = Integer.Parse(Regex.Replace(Section, "[^\d]", ""))
                Dim StartPageName As String = GEini.GetKeyValue(Section, "STARTPAGENAME")
                Dim TitleText As String = GEini.GetKeyValue(Section, "TITLETEXT")
                Dim Database As String = GEini.GetKeyValue(Section, "DATABASE")
                Dim SnapPath As String = GEini.GetKeyValue(Section, "SnapPath")
                Dim TitlePath As String = GEini.GetKeyValue(Section, "TitlePath")
                Dim Enabled As String = GEini.GetKeyValue(Section, "Enabled")
                Dim RomPath As String = GEini.GetKeyValue(Section, "RomPath")

                If StartPageName <> Nothing Then
                    ' MsgBox(EmuNumber & ", " & StartPageName & ", " & TitleText & ", " & Database)
                    emudt.Rows.Add(EmuNumber, StartPageName, TitleText, Database, SnapPath, TitlePath, Enabled, RomPath)
                End If

            End If
        Next
        emudt.Rows.Add(-1, "All", "dummy", "dummy", "dummy", "dummy", True, "dummy")
        emudt.Rows.Add(0, "MAME", "dummy", "[Arcade] Arcade (Mame)", "dummy", "dummy", True, "dummy")

        _status.DGV.DataSource = emudt

        Dim dv As New DataView(emudt)
        dv.Sort = "STARTPAGENAME ASC"
        Dim retdt As New DataTable("UserEmulators")
        retdt = dv.ToTable

        Return retdt
    End Function

    Private Sub CheckPluginInstall()
        If Not (Directory.Exists(PluginAppDir)) Then
            Directory.CreateDirectory(PluginAppDir)
            MsgBox("Warning: this is your first time running Custom Lists. This Plugin manipulates your GameEx favourites list to construct custom, dynamic lists. If you want to preserve your pre-existing favourites list: " & vbCr & vbCr &
                   "- Go to Settings and select ""Show Favourites column""" & vbCr &
                   "- Make a new list" & vbCr &
                   "- Select all the games with a ""1"" in the favorites column then transfer them to your new list. ")
        End If

    End Sub

    Private Sub ShowCGEChB_CheckedChanged(sender As Object, e As EventArgs) Handles ShowCGEChB.CheckedChanged
        If sender.checked = True Then
            myset.ShowWithGameEx = True
        Else
            myset.ShowWithGameEx = False
        End If
        ' myset.SaveSetts()

    End Sub



    Private Sub ShowDebugWindowChB_CheckedChanged(sender As Object, e As EventArgs) Handles ShowDebugWindowChB.CheckedChanged
        If sender.checked = True Then
            myset.ShowDebugWindow = True
        Else
            myset.ShowDebugWindow = False
        End If
    End Sub


    Private Sub KeepLogChB_CheckedChanged(sender As Object, e As EventArgs) Handles KeepLogChB.CheckedChanged
        If sender.checked = True Then
            myset.KeepLog = True
        Else
            myset.KeepLog = False
        End If
    End Sub

    Private Sub LogDebugChB_CheckedChanged(sender As Object, e As EventArgs) Handles LogDebugChB.CheckedChanged
        If sender.checked = True Then
            myset.DebugLog = True
        Else
            myset.DebugLog = False
        End If
    End Sub

    Private Sub CListDGV_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles CListDGV.DataError
        '_log.err("Error at (row,col): " & e.RowIndex & "," & e.ColumnIndex)
        '_log.err("Details: " & e.Exception.Message)
    End Sub

    Private Sub GameCB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles GameCB.DropDown
        Dim myCombo As ComboBox = CType(sender, ComboBox)
        Dim cbWidth As Integer = myCombo.DropDownWidth
        Dim drawGraphics As Graphics = myCombo.CreateGraphics
        Dim myFont As Font = myCombo.Font
        Dim longestItem As Integer
        For Each cbItems As DataRowView In CType(sender, ComboBox).Items
            longestItem = (CType(drawGraphics.MeasureString(cbItems.Item("RomFile"), myFont).Width, Integer))
            If cbWidth < longestItem Then
                cbWidth = longestItem
            End If
        Next
        myCombo.DropDownWidth = cbWidth
    End Sub

    Private Sub SysCB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles SysCB.SelectedIndexChanged
        '_log.echo("syscb value: " & SysCB.SelectedValue.ToString)
        If SysCB.SelectedValue = -1 Then
            _GEdataDV.RowFilter = Nothing
        Else
            _GEdataDV.RowFilter = "EmuNumber = " & SysCB.SelectedValue
        End If
    End Sub

    Private Sub ListViewCB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListViewCB.SelectedIndexChanged
        Select Case ListViewCB.Text
            Case "All"
                _GEdataDV.RowFilter = Nothing
            Case "Selected"
                _GEdataDV.RowFilter = "Select = true"
            Case "On List"
                _GEdataDV.RowFilter = "OnList = true"
            Case "On List or Selected"
                _GEdataDV.RowFilter = "Select = true or OnList = true"
        End Select
    End Sub

    Private Sub GameCB_SelectedIndexChanged_1(sender As Object, e As EventArgs) Handles GameCB.SelectedIndexChanged
        If formshown = False Then Return
        ' ListViewCB.Text = "All"
        _GEdataDV.Sort = "RomFile = " & GameCB.Text
    End Sub



    Private Sub FindROMBT_Click(sender As Object, e As EventArgs) Handles FindROMBT.Click
        For Each dgvrow As DataGridViewRow In CListDGV.Rows
            If dgvrow.Cells("RomFile").Value = GameCB.Text Then
                CListDGV.Rows(dgvrow.Index).Selected = True
                CListDGV.FirstDisplayedScrollingRowIndex = dgvrow.Index
            End If
        Next
        ' _GEdataDV.RowFilter = "RomFile = '" & GameCB.Text & "'"
    End Sub

    Private Sub ClearSelBT_Click(sender As Object, e As EventArgs) Handles ClearSelBT.Click
        For Each row As DataRow In _GEdata.Rows
            If row.Item("Select") = True Then
                row.Item("Select") = False
            End If
        Next
    End Sub



    Private Sub SelToListBT_Click(sender As Object, e As EventArgs) Handles SelToListBT.Click
        SelectedToList()
    End Sub
    Private Sub RemSelBT_Click(sender As Object, e As EventArgs) Handles RemSelBT.Click
        RemSelectedFromList()
    End Sub

    Private Sub SelectedToList()
        Dim ListNo As Integer = CInt(IDTextBox.Text)

        For Each row As DataRow In _GEdata.Rows
            If row.Item("Select") = True And row.Item("OnList") = False Then
                'Update OnList
                row.Item("onList") = True
                'Add to GameListMap
                Dim nrow As DataRow = CListDS.Tables("GameListMap").NewRow
                nrow("ListID") = ListNo
                nrow("EmuNumber") = row.Item("EmuNumber")
                nrow("RomFile") = row.Item("RomFile")
                CListDS.Tables("GameListMap").Rows.Add(nrow)
            End If
        Next

        CListDS.WriteXml(XMLFile)

    End Sub

    Private Sub RemSelectedFromList()
        Dim ListNo As Integer = CInt(IDTextBox.Text)

        For Each row As DataRow In _GEdata.Rows
            If row.Item("Select") = True And row.Item("OnList") = True Then
                'Update OnList
                row.Item("onList") = False
                'Add to GameListMap
                Dim delrow() As DataRow = CListDS.Tables("GameListMap").Select("ListID = " & ListNo &
                                                                        " AND RomFile = '" & row.Item("RomFile") & "' " &
                                                                        "AND EmuNumber = " & row.Item("EmuNumber"))
                CListDS.Tables("GameListMap").Rows.Remove(delrow(0))
            End If
        Next

        CListDS.WriteXml(XMLFile)

    End Sub


    Private Sub LoadListsToCListDGV()
        Dim ListNo As Integer = CInt(IDTextBox.Text)

        For Each row As DataRow In _GEdata.Rows
            'If row.Item("Select") = True Then row.Item("Select") = False
            If row.Item("OnList") = True Then row.Item("OnList") = False
        Next

        Dim GListMap As DataView
        GListMap = CListDS.Tables("GameListMap").DefaultView
        GListMap.RowFilter = "ListID = " & ListNo
        _status.echo("Glistsize: " & GListMap.Count)

        For Each row As DataRow In GListMap.ToTable.Rows
            _status.echo("GList row: " & row.Item("RomFile"))
            Dim hitrow() As DataRow
            hitrow = _GEdata.Select("RomFile = '" & row.Item("RomFile") & "' AND EmuNumber = " & row.Item("EmuNumber"))
            hitrow(0).Item("OnList") = True
        Next

    End Sub

    Private Sub SaveLists()
        Me.Validate()
        ListBindingSource.EndEdit()
        CListDS.WriteXml(XMLFile)

        'referesh icons
        ListsImgUpdate()

    End Sub


    'Private Sub ItemTypeComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ItemTypeComboBox.SelectedIndexChanged
    '    If sender.text = "Root Folder" Then
    '        ParentComboBox.Enabled = False
    '    Else
    '        ParentComboBox.Enabled = True
    '    End If
    'End Sub


    Private Sub IDTextBox_TextChanged(sender As Object, e As EventArgs) Handles IDTextBox.TextChanged
        _status.echo("ID changed to: " & IDTextBox.Text)

        SaveLists()

        ChangePicture(CInt(IDTextBox.Text))
        'disable if Root folder
        If sender.text = "-1" Then
            NameTextBox.Enabled = True
            URLTextBox.Enabled = False
            URLCB.Enabled = False
            OrderInListTextBox.Enabled = False
            ItemTypeComboBox.Enabled = False
            ParentComboBox.Enabled = False
        Else
            NameTextBox.Enabled = True
            URLTextBox.Enabled = True
            OrderInListTextBox.Enabled = True
            ItemTypeComboBox.Enabled = True
            ParentComboBox.Enabled = True
            URLCB.Enabled = True
        End If

        LoadListsToCListDGV()

        Dim trow() As DataRow = CListDS.Tables("List").Select("ID = " & IDTextBox.Text)
        _status.DGV.DataSource = CListDS.Tables("List")
        ListLB.Text = trow(0)("Name")

        'enable/disable Title TB
        If trow(0)("ItemType") = "List" Then
            TitleTextBox.Enabled = False
            TopRightCtrlsPanel.Enabled = True
            URLTextBox.Enabled = True
        Else
            TitleTextBox.Enabled = True
            TopRightCtrlsPanel.Enabled = False
            URLTextBox.Enabled = False
        End If

        'referesh icons
        ListsImgUpdate()

        ListLB.Text = trow(0)("Name")

    End Sub

    Private Sub ChangePicture(IDin As Integer)
        _status.echo("============================================")
        _status.echo("change picture started. ID: " & IDin)

        Dim trow() As DataRow = CListDS.Tables("List").Select("ID = " & IDin)
        Dim itemimage As String = NotNull(trow(0)("ImagePath"), "")
        Dim itemtype As String = NotNull(trow(0)("ItemType"), "")

        _status.echo("Change picture. ID, type, image: " & IDin & ", " & itemimage & ", " & itemtype)

        If NotNull(itemimage, "") = "" Or (File.Exists(itemimage) = False) Then
            _status.echo("Img null or file doesn't exist")
            _status.echo("Filename:" & ImagePathTextBox.Text.Trim)
            If IDin = -1 Then
                _status.echo("Root detected - using Main default")
                ListItemImgPB.Image = SafeImageFromFile(IconsPath & "ListsMain.png")
                ListItemImgPB.Tag = IconsPath & "ListsMain.png"
                Return
            End If
            Select Case itemtype
                Case "List"
                    _status.echo("Item type is List - using this")
                    ListItemImgPB.Image = SafeImageFromFile(IconsPath & "ListGames.png")
                    ListItemImgPB.Tag = IconsPath & "ListGames.png"
                Case "Folder"
                    _status.echo("Item type is folder - using this")
                    ListItemImgPB.Image = SafeImageFromFile(IconsPath & "ListFolder.png")
                    ListItemImgPB.Tag = IconsPath & "ListFolder.png"
            End Select
        Else
            _status.echo("must be existing file.")
            ListItemImgPB.Image = SafeImageFromFile(itemimage)
            ListItemImgPB.Tag = itemimage
        End If
    End Sub

    Private Sub ParentComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ParentComboBox.SelectedIndexChanged
        ParentTextBox.Text = ParentComboBox.SelectedValue
    End Sub

    Private Sub ParentTextBox_TextChanged(sender As Object, e As EventArgs) Handles ParentTextBox.TextChanged
        'set parent folder combo to parentid
        '_status.echo("HERE: " & CInt(ParentTextBox.Text))
        '_status.echo("count: " & ParentComboBox.Items.Count)
        'For Each item As String In ParentComboBox.Items
        '    _status.echo(item)
        'Next

        'Filter Orders List
        ' _ListsBS.Filter = "[Parent] = '" & ParentTextBox.Text & "'"

        ParentComboBox.SelectedValue = CInt(ParentTextBox.Text)
        '   ParentBoxTB.Text = ParentComboBox.Text
        ListNodesCB.SelectedValue = ParentTextBox.Text
    End Sub

    Private Sub ListsDGV_DataError(sender As Object, e As DataGridViewDataErrorEventArgs) Handles ListsDGV.DataError
        _status.echo("Dataerror: " & e.Exception.Message, True)

    End Sub

    Private Sub DataGridView1_CellPainting(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) _
                  Handles ListsDGV.CellPainting
        If e.RowIndex = -1 AndAlso e.ColumnIndex = -1 Then
            e.Paint(e.CellBounds, DataGridViewPaintParts.All And Not DataGridViewPaintParts.ContentForeground)
            e.Graphics.DrawImage(My.Resources.folderUP, New Point(e.CellBounds.Top + 2, e.CellBounds.Left + 2))
            e.Handled = True
        End If
    End Sub

    Private Sub ListsDGV_RowHeaderMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles ListsDGV.RowHeaderMouseClick
        Dim ListID As Integer = ListsDGV.Rows(e.RowIndex).Cells("ID").Value
        _status.echo("ListsDGV List ID: " & ListID)

        Dim pos As Integer = ListBindingSource.Find("ID", ListID)
        ListBindingSource.Position = pos
    End Sub

    Private Sub ListNodesCB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ListNodesCB.SelectedIndexChanged
        _ListsBS.Filter = "[Parent] = " & ListNodesCB.SelectedValue
    End Sub

    Private Function NextWritableMenu(MenuNo As Integer) As Integer

        _status.echo(vbCr & ">> Check Next Section Menu Number Routine.")
        _status.echo("MenuNo in (present menu): " & MenuNo)

        Dim GECMenuIni As New IniFile
        GECMenuIni.Load(Application.StartupPath() & "\CONFIG\CustomMenu.ini")

        Dim WorkingMenuNo As Integer = MenuNo
        Dim SectionList As ArrayList = GECMenuIni.SectionList

        Do 
            WorkingMenuNo += 1
            _status.echo("Testing: MENU_" & WorkingMenuNo)
            _status.echo("Menu exists? " & SectionList.Contains("MENU_" & WorkingMenuNo))
            _status.echo("CUSTOMLIST key? " & GECMenuIni.GetKeyValue("MENU_" & WorkingMenuNo, "CUSTOMLIST") = "True")
        Loop Until Not (SectionList.Contains("MENU_" & WorkingMenuNo)) Or
            (SectionList.Contains("MENU_" & WorkingMenuNo) And GECMenuIni.GetKeyValue("MENU_" & WorkingMenuNo, "CUSTOMLIST") = "True")

        _status.echo("Next avaiable menu: " & WorkingMenuNo)

        Return WorkingMenuNo

        'GECMenuIni.GetKeyValue("MENU_" & WorkingMenuNo, "CUSTOMLIST") = "True" or





        '        If GECMenuIni.SectionList.Contains("MENU_" & MenuNo + 1) Then
        '            _status.echo("Section Found")
        '            _status.echo("Customlist: " & GECMenuIni.GetKeyValue("MENU_" & MenuNo, "CUSTOMLIST"))
        '            If GECMenuIni.GetKeyValue("MENU_" & MenuNo + 1, "CUSTOMLIST") = "True" Then
        '                _status.echo("Menu is a CustomLists Menu - returning Passed in MenuNo: " & MenuNo)
        '                Return MenuNo
        '            Else
        '                _status.echo("No CUTSOMLIST flag found - therefore likely GameEx Custom menu - Returning: " & MenuNo + 1)
        '                Return MenuNo + 1
        '                ' MsgBox("Warning: CuastomLists has detected an overlap of CustomLists Folders/Items and GameEx's CustomMenus Folder/Items. This is often caused by adding GameEx CustomMenus after Building a List in CustomLists WITHOUT deleting the CustomList lists first. This can cause squiffy operation. Try going into GameEx CustomMenus, deleting the CustomLists folder, then rebuilding the Custom Lists in the configuration. See documentation for more information.", MsgBoxStyle.Exclamation)
        '            End If
        '        Else
        '            _status.echo("Menu doesn't exist. Returning MenuNo: " & MenuNo)
        '            Return MenuNo
        '        End If

    End Function

    Private Function UniqueItemOrder(value As Integer, DList As List(Of Integer)) As Integer

        DList.Sort()

        If HasDuplicateValueInt(DList, value) Then
            _status.echo(vbCr & "Duplicate Item Order Found - returning highest+1: " & DList(DList.Count - 1) + 1)
            DList.Add(DList(DList.Count - 1) + 1)
            Return DList(DList.Count - 1)
        Else
            _status.echo("No duplicates found, returning value: " & value)
            DList.Add(value)
            Return value
        End If

    End Function

    Private Function HasDuplicateValueInt(ListIn As List(Of Integer), Value As Integer) As Boolean
        _status.echo(">>Test for duplicates. Value: " & Value)
        _status.echo("List Items:")
        For Each val As Integer In ListIn
            _status.echo(val)
            If val = Value Then
                _status.echo("Has duplicates")
                Return True
            End If
        Next
        _status.echo("NO duplicates")
        Return False
    End Function



    Private Sub MakeCListIniBT_Click(sender As Object, e As EventArgs) Handles MakeCListIniBT.Click
        _log.echo(vbCr & "--------------------------------------------------------")
        _log.echo("", "CustomMenu.ini Make routine.")

        'Discern which folder to build to
        _log.echo("Folder to build to: " & CustMenuSecs.Item(RootCB.Text))
        Dim DestSec As String = CustMenuSecs.Item(RootCB.Text)

        '{"ListFolder", "ListGames", "ListLoad", "ListsMain", "ListView", "ListWWW"}

        'Setup holding datatable
        Dim CMenuDT As New DataTable
        CMenuDT.Columns.Add("Section", GetType(String))
        CMenuDT.Columns.Add("Key", GetType(String))
        CMenuDT.Columns.Add("Value", GetType(String))

        Dim Working As New DataTable
        Working.Merge(CListDS.Tables("List"))
        Working.Columns.Add("MenuNo", GetType(Integer))
        Working.Columns.Add("ItemNo", GetType(Integer))
        Working.Columns.Add("CMenuTitle", GetType(String))
        Working.Columns.Add("ValMType", GetType(String))
        Working.Columns.Add("ValName", GetType(String))
        Working.Columns.Add("ValMenuNo", GetType(String))
        Working.Columns.Add("ValImg", GetType(String))

        'sort it
        Dim workingDV As New DataView(Working)
        workingDV.Sort = "Parent ASC, OrderInList ASC"

        SWorking = workingDV.ToTable()

        'temp
        _status.DGV.DataSource = SWorking
        _status.DGV2.DataSource = CMenuDT

        With _status.DGV
            .Columns("ID").DisplayIndex = 1
            .Columns("Name").Frozen = True
        End With

        'determine first available 
        _log.echo("Determine Menu_x Start number")
        Dim drow() As DataRow = SWorking.Select("ID = -1") ' this gets root item for passing name to function below
        Dim StartingMenuNo As Integer = DetermineMenuStart(drow(0)("Name"), DestSec)
        If StartingMenuNo = -1 Then
            _log.err("Start number returned as -1 meaning error in parsing. Use debug to see details. Not finishing routine")
            Return
        Else
            _log.echo("Menu start number: " & StartingMenuNo)
        End If

        PBar1.Minimum = 0
        PBar1.Maximum = SWorking.Rows.Count * 5
        PBar1.Value = 0
        PBar1.BringToFront()
        PBar1.Visible = True

        Dim TMenuNo As Integer = StartingMenuNo
        Dim TItemNo As Integer = 1
        Dim TTitle As String = "TempTitle"
        Dim WorkingParent As Integer = SWorking.Rows(0).Item("Parent")

        Dim OrderStack As New List(Of Integer)

        _status.echo(">>>>>>>>>FIRST PASS")
        For Each row As DataRow In SWorking.Rows

            _status.echo("------------------------------------------------")
            _status.echo("Row: " & row("Name"))

            If row("Parent") <> WorkingParent Then
                WorkingParent = row("Parent")
                TItemNo = 1
                OrderStack.Clear()
                '_status.echo("Return from check menu number: " & IncIfGECustomMenu(TMenuNo) & vbCr)
                TMenuNo = NextWritableMenu(TMenuNo)
            End If

            'first check not root folder
            If row("ID") = -1 Then
                _status.echo("Root folder found")
                row("MenuNo") = -1
                row("ItemNo") = DetermineRootNumber(row("Name"), DestSec)
                ' row("ItemNo") = TItemNo
                row("ValMType") = "-1"
                row("ValName") = row("Name")
                row("ValMenuNo") = StartingMenuNo
                row("ValImg") = ImgTextAndProcess(NotNull(row("ImagePath"), ""), "ListsMain")
                ' *** FILL ITEM NO HERE? - spearate function iterated through exiting [root] seciton - get last number
                Continue For
            End If

            'Get Parent Details: 
            Dim prow() As DataRow = SWorking.Select("ID = " & row("Parent"))

            row("CMenuTitle") = prow(0)("Title")
            row("MenuNo") = TMenuNo

            If row("ItemType") = "Folder" Then
                'row("ItemNo") = NotNull(row("OrderInList"), "1")
                row("ItemNo") = UniqueItemOrder(NotNull(row("OrderInList"), "-1"), OrderStack)
                row("ValMType") = "-1"
                row("ValName") = row("Name")
                row("ValImg") = ImgTextAndProcess(NotNull(row("ImagePath"), ""), "ListFolder")
            ElseIf row("ItemType") = "List" Then
                row("ItemNo") = UniqueItemOrder(NotNull(row("OrderInList"), "-1"), OrderStack)
                row("ValMType") = "-1"
                row("ValName") = row("Name")
                row("ValImg") = ImgTextAndProcess(NotNull(row("ImagePath"), ""), "ListGames")
            Else
                _log.err("Item without Folder or Item classifiction: " & row("Name"))
                _log.err("Using default image and treating as folder pointing to itself")
                row("ItemNo") = UniqueItemOrder(NotNull(row("OrderInList"), "-1"), OrderStack)
                row("ValMType") = "-1"
                row("ValName") = row("Name")
                row("ValImg") = "ListsMain"
            End If
            TItemNo += 1
            PBar1.Value += 1
        Next

        TMenuNo = NextWritableMenu(TMenuNo)  ' increments to next free menu number slot
        'CheckMenusOverlap(TMenuNo)
        _status.echo("1st pass finished. Next available menu number = " & TMenuNo.ToString)

        _status.echo("2nd Pass - Expanding Lists to new Menus")

        'second pass - polulate:
        ' ValMenuNumber from lookup MenuNo via ID + ParetnID
        For i As Integer = SWorking.Rows.Count - 1 To 0 Step -1
            Dim row As DataRow = SWorking.Rows(i)
            If row("ItemType") = "List" Then
                _status.echo("Item type List found: " & row("Name"))
                'update ListID_MenuIDMap
                UpdateListMenuIDMap(CInt(row("ID")), TMenuNo)

                Dim nrow As DataRow = SWorking.NewRow
                'LOAD
                nrow("Name") = "> Load [" & row("Name") & "]"
                nrow("ItemType") = "ListMenu (Load)"
                nrow("CMenuTitle") = row("Name")
                nrow("MenuNo") = TMenuNo
                nrow("ImagePath") = ImgTextAndProcess("", "ListLoad")
                nrow("OrderInList") = 1
                nrow("Parent") = row("ID")
                nrow("Title") = row("Name")
                nrow("ItemNo") = 1
                nrow("ValMType") = 8
                nrow("ValName") = "Load List [" & row("Name") & "]"
                nrow("ValMenuNo") = 0
                nrow("ValImg") = ImgTextAndProcess("", "ListLoad")
                SWorking.Rows.Add(nrow)
                'VIEW
                nrow = SWorking.NewRow
                nrow("Name") = "> View [" & row("Name") & "]"
                nrow("ItemType") = "ListMenu (View)"
                nrow("CMenuTitle") = row("Name")
                nrow("MenuNo") = TMenuNo
                nrow("ImagePath") = ImgTextAndProcess("", "ListView")
                nrow("OrderInList") = 2
                nrow("Parent") = row("ID")
                nrow("Title") = row("Name")
                nrow("ItemNo") = 2
                nrow("ValMType") = 12
                nrow("ValName") = "View List"
                nrow("ValMenuNo") = 0
                nrow("ValImg") = ImgTextAndProcess("", "ListView")
                SWorking.Rows.Add(nrow)
                'URL
                If NotNull(row("URL"), "") <> "" AndAlso row("URL") <> "-1" Then
                    nrow = SWorking.NewRow
                    nrow("Name") = "> URL [" & row("Name") & "]"
                    nrow("ItemType") = "ListMenu (URL)"
                    nrow("CMenuTitle") = row("Name")
                    nrow("MenuNo") = TMenuNo
                    nrow("ImagePath") = ImgTextAndProcess("", "ListWWW")
                    nrow("OrderInList") = 3
                    nrow("Parent") = row("ID")
                    nrow("Title") = row("Name")
                    nrow("ItemNo") = 3
                    nrow("ValMType") = 3
                    nrow("ValName") = "View Website"
                    nrow("ValMenuNo") = row("URL") ' edited here from 99
                    nrow("ValImg") = ImgTextAndProcess("", "ListWWW")
                    SWorking.Rows.Add(nrow)
                End If
                TMenuNo = NextWritableMenu(TMenuNo)
                ' CheckMenusOverlap(TMenuNo)
            End If
            PBar1.Value += 1
        Next

        _status.echo("2nd pass finished. Last pass - find menu numbers via parent")

        For Each row As DataRow In SWorking.Rows
            _status.echo("Processing Row: " & row("Name"))
            If NotNull(row("ValMenuNo"), "") = "" Then
                _status.echo("Missing Menu number")
                Dim prow() As DataRow = SWorking.Select("[Parent] = " & row("ID"))
                If prow.Length = 0 Then
                    _status.echo("Row is childless - set menu to non menu number (99).")
                    row("ValMenuNo") = 99
                Else
                    row("ValMenuNo") = prow(0)("MenuNo")
                End If

            End If
            PBar1.Value += 1
        Next

        '{"ListFolder", "ListGames", "ListLoad", "ListsMain", "ListView", "ListWWW"}

        'END OF DGV POP
        ' ===============================================================================================
        ' ===============================================================================================


        'TRANSFER TO INI DGV
        _status.echo("Populating ini table")
        Dim ncrow As DataRow = CMenuDT.NewRow
        For Each row As DataRow In SWorking.Rows
            _status.echo("Processing: " & row("Name"))

            ncrow = CMenuDT.NewRow

            'SECTION
            Dim SectionName As String = Nothing
            If row("MenuNo") = -1 Then
                SectionName = DestSec
            Else
                SectionName = "MENU_" & row("MenuNo")
            End If

            'Key
            Dim KeyText As String = Nothing
            KeyText = "Item_" & row("ItemNo")

            'Value
            Dim ValueText As String = Nothing
            ValueText = row("ValMType") & "," & row("ValName") & "," & row("ValMenuNo") & "," & row("ValImg")

            Try
                ncrow("Section") = SectionName
                ncrow("Key") = KeyText
                ncrow("Value") = ValueText

                CMenuDT.Rows.Add(ncrow)
            Catch ex As Exception
                _status.echo(ex.Message, True)
            End Try

            'And Add CustomLists Flag
            ncrow = CMenuDT.NewRow
            ncrow("Section") = SectionName
            ncrow("Key") = "CUSTOMLIST"
            ncrow("Value") = "True"
            CMenuDT.Rows.Add(ncrow)

        Next
        'then again to put in TITLES
        For Each row As DataRow In SWorking.Rows
            ncrow = CMenuDT.NewRow
            'SECTION
            Dim SectionName As String = Nothing
            If row("MenuNo") = -1 Then
                SectionName = DestSec
            Else
                SectionName = "MENU_" & row("MenuNo")
            End If

            Dim trow() As DataRow = CMenuDT.Select("Section = '" & SectionName & "' and Key = 'TITLE'")

            If trow.Length = 0 Then

                'Value
                Dim ValueText As String = Nothing
                ValueText = NotNull(row("CMenuTitle"), "")
                If ValueText <> "" Then
                    ncrow("Section") = SectionName
                    ncrow("Key") = "TITLE"
                    ncrow("Value") = ValueText
                    CMenuDT.Rows.Add(ncrow)
                End If

            End If
        Next

        PBar1.Value = PBar1.Maximum * 95 / 100

        'WRITE THE BUGGER!
        Dim GECMenuIni As New IniFile
        GECMenuIni.Load(Application.StartupPath() & "\CONFIG\CustomMenu.ini")
        'delete existing secitons
        For Each row As DataRow In CMenuDT.Rows
            If row("Section") <> DestSec Then
                GECMenuIni.RemoveSection(row("Section"))
            End If
        Next

        For Each row As DataRow In CMenuDT.Rows
            If row("Section") = DestSec Then
                GECMenuIni.SetKeyValue(DestSec, row("Key"), row("Value"))
            Else
                GECMenuIni.SetKeyValue(row("Section"), row("Key"), row("Value"))
            End If
        Next

        'Address sloppy GE coding (have to null lines)
        Dim ItemHigh As Integer = 0
        Dim Itemno As Integer = 0
        For Each row As DataRow In CMenuDT.Rows
            If row("Section") <> DestSec Then
                Integer.TryParse(row("Key").Replace("Item_", ""), Itemno)
                If Itemno > ItemHigh Then ItemHigh = Itemno
            End If
        Next
        For Each section As String In GECMenuIni.SectionList
            If section.Contains("MENU_") Then
                _status.echo("Section: " & section)
                For i As Integer = 1 To ItemHigh
                    If GECMenuIni.GetKeyValue(section, "Item_" & i) = String.Empty Then
                        _status.echo("Item_" & i & "missing. Making...")
                        GECMenuIni.SetKeyValue(section, "Item_" & i, " ")
                    End If
                Next
            End If
        Next
        PBar1.Value = 0
        PBar1.Visible = False
        PBar1.SendToBack()

        'Now tidy ini
        _status.echo("========================================================")
        _status.echo("Cleaning Ini")
        Dim NewIni As New IniFile
        For Each cmenusec As IniFile.IniSection In GECMenuIni.Sections
            _status.echo("SECTION: " & cmenusec.Name)
            NewIni.AddSection(cmenusec.Name)
            ' Remove any keys without values
            For Each key As IniFile.IniSection.IniKey In cmenusec.Keys
                _status.echo(">> KEY, Value: " & key.Name & ", " & key.Value)
                If key.Value IsNot Nothing And key.Value <> "" And key.Value <> " " Then
                    NewIni.SetKeyValue(cmenusec.Name, key.Name, key.Value)
                End If
            Next
        Next
        NewIni.Save(Application.StartupPath() & "\CONFIG\CustomMenu.ini")

        'GECMenuIni.Save(Application.StartupPath() & "\CONFIG\CustomMenu.ini")






        MsgBox("List Successfully built.", MsgBoxStyle.Information, "Custom Lists")

    End Sub

    Private Sub UpdateListMenuIDMap(ListID As Integer, MenuID As Integer)
        _status.echo("Update Menu/List ID map. ListID + Menu ID: " & ListID & ", " & MenuID)

        Dim row() As DataRow = CListDS.Tables("IDMenuMap").Select("ListID = " & ListID)

        If row.Length = 0 Then
            _status.echo("No maps found - making new")
            Dim nrow As DataRow = CListDS.Tables("IDMenuMap").NewRow
            nrow("ListID") = ListID
            nrow("MenuID") = MenuID
            CListDS.Tables("IDMenuMap").Rows.Add(nrow)
        Else
            _status.echo("Maps already exist - deleting old and writing new")
            For Each drow As DataRow In row
                _status.echo("Old Map dleted..")
                CListDS.Tables("IDMenuMap").Rows.Remove(drow)
            Next
            Dim nrow As DataRow = CListDS.Tables("IDMenuMap").NewRow
            nrow("ListID") = ListID
            nrow("MenuID") = MenuID
            CListDS.Tables("IDMenuMap").Rows.Add(nrow)
            _status.echo("New Map written..")
        End If

        CListDS.WriteXml(XMLFile)
    End Sub

    Private Function SubMenuNumber(ParentID As Integer) As Integer
        _status.echo(">> Return Sub Menu NUmber")
        _status.echo("Parent ID: " & ParentID)
        Dim drow() As DataRow = SWorking.Select("ID = " & ParentID)

    End Function

    Public Shared Function NotNull(Of T)(ByVal Value As T, ByVal DefaultValue As T) As T

        If Value Is Nothing OrElse IsDBNull(Value) Then
            Return DefaultValue
        Else
            Return Value
        End If
    End Function

    Private Function ImgTextAndProcess(fullfile As String, defaultimg As String) As String

        '{"ListFolder", "ListGames", "ListLoad", "ListsMain", "ListView", "ListWWW"}
        _log.echo(">> Img Text and Process function")
        _log.echo("File passed: " & fullfile)
        _log.echo("Default passed: " & defaultimg)


        Dim PassedFileBare As String = Nothing

        If fullfile = Nothing Or fullfile = "" Then
            _log.echo("No file passed - using default")
            Return defaultimg
        End If

        Try
            PassedFileBare = Path.GetFileNameWithoutExtension(fullfile)
        Catch
            _log.echo("Whist get filename without extention. Using defualt.")
            Return defaultimg
        End Try



        If File.Exists(fullfile) Then
            Dim filename As String = Path.GetFileName(fullfile)
            _log.echo("Destination: " & IconsPath & filename)
            _log.echo("File specified in setup exists. Copying to folder: " & IconsPath & filename)
            _log.echo("DEBUG: " & fullfile & vbCr & IconsPath & filename)
            _log.echo("SAME? " & String.Compare(fullfile, IconsPath & filename, True))
            If String.Compare(fullfile, IconsPath & filename, True) <> 0 Then
                _log.echo("Files NOT the same.. Copying.")
                File.Copy(fullfile, IconsPath & filename, True)
            End If
            Return PassedFileBare
        Else
            _log.echo("File specified in setup DOES NOT exist. Chekcing if in Logos folder...")
            If My.Computer.FileSystem.FileExists(IconsPath & PassedFileBare & ".png") Or
                My.Computer.FileSystem.FileExists(IconsPath & PassedFileBare & ".jpg") Then
                _log.echo("File does exist in the Logos folder - using this filename")
                Return PassedFileBare
            Else
                _log.echo("File does NOT exist in the Logos folder either - using default")
                Return defaultimg
            End If

        End If

        '  If Not My.Computer.FileSystem.FileExists(IconsPath & filename & ".png") Then
        _log.echo("Bombed out - returing default")
        Return defaultimg

    End Function



    Private Function DetermineRootNumber(Name As String, destsec As String) As Integer
        _status.echo("DETEMRINE ROOT NUMBER")
        _status.echo("Recieved Name: " & Name)

        Dim RetPage As Integer = -1

        Dim GECMenuIni As New IniFile
        GECMenuIni.Load(Application.StartupPath() & "\CONFIG\CustomMenu.ini")

        Dim HighestItemNo As Integer = -1

        For Each key As IniFile.IniSection.IniKey In GECMenuIni.GetSection(destsec).Keys
            Dim value As String = NotNull(key.Value, "")
            _status.echo("Key, Value: " & key.Name & ", " & value)
            If value.Contains("-1," & Name & ",") Then
                _status.echo("HIT returning item number")
                Integer.TryParse(key.Name.Replace("Item_", ""), RetPage)
                _status.echo("Returning: " & RetPage)
                Return RetPage
            End If

            Dim ItemNo As Integer = -1
            Integer.TryParse(key.Name.Replace("Item_", ""), ItemNo)
            If ItemNo > HighestItemNo Then HighestItemNo = ItemNo
        Next

        If HighestItemNo > -1 Then
            _status.echo("Existing items in [Root] - returning next available number: " & HighestItemNo + 1)
            Return HighestItemNo + 1
        End If

        _status.echo("Bombed out", True)
        Return -1

    End Function

    Private Function DetermineMenuStart(Name As String, DestMenu As String) As Integer

        _status.echo("DETEMRINE MENU START NUMBER ROUTINE")
        _status.echo("Recieved Name: " & Name)

        Dim RetPage As Integer = -1

        Dim GECMenuIni As New IniFile
        GECMenuIni.Load(Application.StartupPath() & "\CONFIG\CustomMenu.ini")


        For Each key As IniFile.IniSection.IniKey In GECMenuIni.GetSection(DestMenu).Keys
            Dim value As String = NotNull(key.Value, "")
            _status.echo("Key, Value: " & key.Name & ", " & value)
            If value.Contains("-1," & Name & ",") Then
                _status.echo("HIT returning page number")
                Dim csv() As String = value.Split(",")
                _status.echo("Page Number: " & csv(2))
                Return CInt(csv(2))
            End If
        Next

        _status.echo("No result from exmaining root. Get number from last 'Menu_x' in ini")
        Dim highest As Integer = -1
        For Each sec As String In GECMenuIni.SectionList
            _status.echo("Section: " & sec)
            Dim fromsec As Integer
            Integer.TryParse(sec.Replace("MENU_", ""), fromsec)

            If fromsec > highest Then highest = fromsec
        Next
        If highest > -1 Then
            _status.echo("Highest number from Parsing CustmMenus.ini: " & highest)
            _status.echo("Returning " & highest + 1 & " to give correct menu number")
            Return highest + 1
        End If

        _status.echo("Bombed out - returning -1")
        Return -1


        'GEThemePath = Application.StartupPath & GEini.GetKeyValue("CachedImages3d", "themedir")
    End Function



    Private Sub ItemTypeComboBox_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ItemTypeComboBox.SelectedIndexChanged


    End Sub

    Private Sub Debug2LogChB_CheckedChanged(sender As Object, e As EventArgs) Handles Debug2LogChB.CheckedChanged
        If sender.checked = True Then
            myset.DebugToLog = True
        Else
            myset.DebugToLog = False
        End If
    End Sub


    Private Sub ListItemImgPB_Click(sender As Object, e As MouseEventArgs) Handles ListItemImgPB.Click
        If e.Button = Windows.Forms.MouseButtons.Right Then
            With OFD1
                .Title = "Please select the Image for this Item"
                .Filter = "PNG|*.png|JPG|*.jpg"
                Try
                    .InitialDirectory = Path.GetDirectoryName(ImagePathTextBox.Text)
                    .FileName = Path.GetFileName(ImagePathTextBox.Text)
                Catch
                    .InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
                End Try

            End With
            If OFD1.ShowDialog = Windows.Forms.DialogResult.OK Then
                ImagePathTextBox.Text = OFD1.FileName
                ListItemImgPB.Image = SafeImageFromFile(OFD1.FileName)
                ListItemImgPB.Tag = OFD1.FileName
            End If
        ElseIf e.Button = Windows.Forms.MouseButtons.Left Then
            If File.Exists(sender.tag) Then
                Dim imgprev As New PictureViewer
                imgprev.Image = SafeImageFromFile(sender.tag)
                imgprev.Show()
            End If
        End If

    End Sub

    Public Shared Function SafeImageFromFile(path As String) As Image
        Using fs As New FileStream(path, FileMode.Open, FileAccess.Read)
            Dim img = Image.FromStream(fs)
            Return img
        End Using
    End Function

    Private Sub ImgDefBT_Click(sender As Object, e As EventArgs) Handles ImgDefBT.Click

        ImagePathTextBox.Text = ""
        If IDTextBox.Text = "-1" Then
            ListItemImgPB.Image = SafeImageFromFile(IconsPath & "ListsMain.png")
            ListItemImgPB.Tag = IconsPath & "ListsMain.png"
        End If

        If ItemTypeComboBox.Text = "List" Then
            ListItemImgPB.Image = SafeImageFromFile(IconsPath & "ListGames.png")
            ListItemImgPB.Tag = IconsPath & "ListGames.png"
        Else
            ListItemImgPB.Image = SafeImageFromFile(IconsPath & "ListFolder.png")
            ListItemImgPB.Tag = IconsPath & "ListFolder.png"
        End If

    End Sub


    Private Sub FontBT_Click(sender As Object, e As EventArgs) Handles FontBT.Click

        With FD1
            .Font = My.Settings.EditorFont
        End With

        If FD1.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.Font = FD1.Font
            My.Settings.EditorFont = FD1.Font
            My.Settings.Save()
        End If
    End Sub

    Private Sub SaveDB3_Click(sender As Object, e As EventArgs)
        _DBOps.SaveGEDb3(_GEdata)
    End Sub

    Public Sub RegenFavesDB3(MenuID As Integer, Optional ListID As Integer = -2)
        Try
            _status.echo("--------------------------------------------------------")
            _status.echo("Regen Faves List sub started")
        _status.echo("Passed MenuID: " & MenuID)
        _status.echo("ListID: " & ListID)

        MenuID = MenuID - 3200
        _status.echo("Final MenuID after -3200: " & MenuID)

        If ListID = -2 Then
            _status.echo("ListID set to -2 which mean optional ListID activation not followed. Proceeding with MenuID")
            _status.echo("Getting ListID from MenuListID Map")
            Dim nrow() As DataRow = CListDS.Tables("IDMenuMap").Select("MenuID = " & MenuID)
            _status.echo("No rows discovered: " & nrow.Length)
            If nrow.Length > 0 Then
                ListID = nrow(0)("ListID")
            Else
                _status.echo("ListID not set due to no matching records.")
            End If

            _status.echo("ListID = " & ListID)
        Else
            _status.echo("ListID Provided in routine. Using this")
        End If

        _status.echo("Final List ID: " & ListID)

        Dim ListNo As Integer = ListID

        'Clear Favourites
        For Each row As DataRow In _GEdata.Rows
            'If row.Item("Select") = True Then row.Item("Select") = False
            If NotNull(row.Item("Favorite"), 0) <> 0 Then row.Item("Favorite") = 0
        Next

        Dim GListMap As DataView
        GListMap = CListDS.Tables("GameListMap").DefaultView
        GListMap.RowFilter = "ListID = " & ListNo
        _status.echo("Glistsize: " & GListMap.Count)

        For Each row As DataRow In GListMap.ToTable.Rows
            _status.echo("GList row: " & row.Item("RomFile"))
            Dim hitrow() As DataRow
            hitrow = _GEdata.Select("RomFile = '" & row.Item("RomFile") & "' AND EmuNumber = " & row.Item("EmuNumber"))
            hitrow(0).Item("Favorite") = True
        Next

            _DBOps.SaveGEDb3(_GEdata)

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End Sub



    Private Sub TestFavesBT_Click(sender As Object, e As EventArgs)
        RegenFavesDB3(-1, CInt(IDTextBox.Text))
    End Sub

    Private Sub ListBindingSource_PositionChanged(sender As Object, e As EventArgs) Handles ListBindingSource.PositionChanged

        'ListNodesCB.DataSource = Nothing
        'ListNodesDV = CListDS.Tables("List").Copy.DefaultView
        'ListNodesDV.RowFilter = "ItemType = 'Folder'"
        'With ListNodesCB
        '    .DisplayMember = "Name"
        '    .ValueMember = "ID"
        '    .DataSource = ListNodesDV
        'End With

    End Sub




    Private Sub ListsDGV_RowsAdded(sender As Object, e As DataGridViewRowsAddedEventArgs) Handles ListsDGV.RowsAdded
        ListsImgUpdate()
    End Sub

    Private Sub ListsDGV_Sorted(sender As Object, e As EventArgs) Handles ListsDGV.Sorted
        ListsImgUpdate()

    End Sub

    Private Sub SortTableBT_Click(sender As Object, e As EventArgs) Handles SortTableBT.Click
        'ListsDGV.Sort(ListsDGV.Columns("ItemType"), System.ComponentModel.ListSortDirection.Ascending)
        Dim number As Integer = 1
        For Each dgvrow As DataGridViewRow In ListsDGV.Rows
            dgvrow.Cells("OrderInList").Value = number
            number += 1
        Next
        ' ListsDGV.Rows(0).Cells("OrderInList").Value = 1
    End Sub


    Private Sub ListBindingNavigatorSaveItem_Click(sender As Object, e As EventArgs) Handles ListBindingNavigatorSaveItem.Click
        SaveLists()
    End Sub

    Private Sub ListDTRowChanged(sender As Object, e As DataRowChangeEventArgs)
        _status.echo(vbCr & "Datarow changed in List DT: " & e.Action)
        If e.Action = DataRowAction.Add Then
            _status.echo("Row changed: " & e.Row.Item("Name"))
            OrderItemsInPeers(e.Row("Parent"))
        End If

        'Dim LastID As Integer = CListDS.Tables("List").Compute("Max(ID)", Nothing)
        'Dim row() As DataRow = CListDS.Tables("List").Select("ID = " & LastID)
        '_status.echo("Last row added: " & LastID & row(0)("Name"))

        'Dim prow() As DataRow = CListDS.Tables("List").Select("Parent = " & row(0)("Parent"))
        'Dim high As Integer = 0
        'For Each srow As DataRow In prow
        '    If srow("OrderInList") > high Then
        '        high = srow("OrderInList")
        '    End If
        'Next
        'row(0)("OrderInList") = high + 1

    End Sub

    Private Sub OrderItemsInPeers(ParentID As Integer)
        'Dim LastID As Integer = CListDS.Tables("List").Compute("Max(ID)", Nothing)
        'Dim row() As DataRow = CListDS.Tables("List").Select("ID = " & LastID)
        '_status.echo("Last row added: " & LastID & row(0)("Name"))
        _status.echo(vbCr & "Order Items Sub")
        Dim prow() As DataRow = CListDS.Tables("List").Select("[Parent] = " & ParentID)
        Dim high As Integer = 0
        For Each srow As DataRow In prow
            _status.echo("Row: " & srow.Item("Name"))
            If srow("OrderInList") > high Then
                high = srow("OrderInList")
            End If
        Next
        _status.echo("High = " & high)
        Dim orders As New List(Of Integer)
        For Each srow As DataRow In prow
            _status.echo("Row: " & srow.Item("Name"))
            If NotNull(srow("OrderInList"), -2) = -2 Then
                _status.echo("order = null. Setting to high + 1= " & high)
                high += 1
                srow("OrderInList") = high
            ElseIf orders.Contains(high) Then
                _status.echo("Dupe order number. Setting to high = " & high)
                high += 1
                srow("OrderInList") = high
            End If
            orders.Add(srow("OrderInList"))
        Next

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs)
        PopulateHtmlApp(0, IDTextBox.Text)
    End Sub

    Public Sub PopulateHtmlApp(MenuID As Integer, Optional ListID As Integer = -2)
        _log.echo("--------------------------------------------------------")
        _log.echo("", "PopulateHtmlApp")
        _log.echo("Passed MenuID: " & MenuID)
        _log.echo("ListID: " & ListID)

        _status.echo("StartupPath: " & Application.StartupPath())

        _status.DGV.DataSource = CListDS.Tables("List")
        _status.DGV2.DataSource = CListDS.Tables("IDMenuMap")

        MenuID = MenuID - 3200
        _log.echo("Final MenuID after -3200: " & MenuID)

        If ListID = -2 Then
            _log.echo("ListID set to -2 which mean optional ListID activation not followed. Proceeding with MenuID")
            _log.echo("Getting ListID from Menu?ListID Map")
            Dim nrow() As DataRow = CListDS.Tables("IDMenuMap").Select("MenuID = " & MenuID)
            ListID = nrow(0)("ListID")
            _log.echo("ListID = " & ListID)
        Else
            _log.echo("ListID Provided in routine. Using this")
        End If

        _log.echo("Final List ID: " & ListID)

        Dim ListNo As Integer = ListID

        Dim srow() As DataRow = CListDS.Tables("List").Select("ID = " & ListNo)

        _status.echo("number of rows: " & srow.Length)

        Dim GEIni As New IniFile
        GEIni.Load(Application.StartupPath() & "\CONFIG\GameEx.ini")
        GEIni.SetKeyValue("htmlapplications", "URL_99", srow(0)("URL"))
        GEIni.SetKeyValue("htmlapplications", "Name_99", srow(0)("Name"))
        GEIni.SetKeyValue("htmlapplications", "Logo_99", "ListWWW")
        GEIni.SetKeyValue("htmlapplications", "MouseEmu_99", "True")
        GEIni.SetKeyValue("htmlapplications", "Hide_99", "False")
        GEIni.SetKeyValue("htmlapplications", "Enabled_99", "True")
        GEIni.Save(Application.StartupPath() & "\CONFIG\GameEx.ini")

        wait(1000)

    End Sub

    Private Sub wait(ByVal interval As Integer)
        Dim sw As New Stopwatch
        sw.Start()
        Do While sw.ElapsedMilliseconds < interval
            ' Allows UI to remain responsive
            Application.DoEvents()
        Loop
        sw.Stop()
    End Sub

    Private Sub ReloadGamesBT_Click(sender As Object, e As EventArgs) Handles ReloadGamesBT.Click
        _GEdata.Clear()
        _GEdata = _DBOps.ImportGEDb3(Application.StartupPath() & "\DATA\DATA.db3", "Data")
        _GEdataDV = _GEdata.DefaultView
        _GEdataDV.Sort = "RomFile ASC"
        CListDGV.DataSource = _GEdataDV

        Dim sellist As New Data.DataColumn("Select", Type.GetType("System.Boolean"))
        sellist.DefaultValue = False
        _GEdata.Columns.Add(sellist)
        sellist.Dispose()

        Dim onlist As New Data.DataColumn("OnList", Type.GetType("System.Boolean"))
        onlist.DefaultValue = False
        _GEdata.Columns.Add(onlist)
        onlist.Dispose()

        Dim gamename As New Data.DataColumn("GameName", Type.GetType("System.String"))
        gamename.DefaultValue = ""
        _GEdata.Columns.Add(gamename)
        gamename.Dispose()

        CListDGV.Columns("OnList").DisplayIndex = 0
        CListDGV.Columns("OnList").ReadOnly = True
        CListDGV.Columns("Select").DisplayIndex = 0
        CListDGV.Columns("GameName").DisplayIndex = 4
        CListDGV.Columns("GameName").ReadOnly = True

    End Sub

    Private Sub GameLookupBT_Click(sender As Object, e As EventArgs) Handles GameLookupBT.Click
        _status.echo(vbCr & "GAME LOOKUP")
        If CListDGV.SelectedRows.Count = 0 Then Return

        For Each dgvrow As DataGridViewRow In CListDGV.SelectedRows
            Dim EmuID As Integer = dgvrow.Cells("EmuNumber").Value
            _status.echo("Emu ID: " & EmuID)

            Dim UserEmurow() As DataRow = CListDS.Tables("UserEmulators").Select("EmuNumber = " & EmuID)
            ' _status.echo("UserEmurow count: " & UserEmurow.Length)

            Dim UserEmuDB As String = UserEmurow(0).Item("Database")
            _status.echo("Database: " & UserEmuDB)

            Dim TempDT As New DataTable
            TempDT.TableName = "Data"
            Try
                ' TempDT = _DBOps.ImportGEDb3(Application.StartupPath() & "\DATA\EMULATORS\" & UserEmuDB & ".db3", "GameData")
                TempDT = _DBOps.SelectFromGEDb3(Application.StartupPath() & "\DATA\EMULATORS\" & UserEmuDB & ".db3",
                                            "GameData", "*",
                                            "WHERE GoodName = '" & dgvrow.Cells("RomFile").Value & "'")

            Catch ex As Exception
                _log.err(ex.Message, "importing ge data")
            End Try

            _status.DGV.DataSource = TempDT
            If TempDT.Rows.Count > 0 Then
                dgvrow.Cells("GameName").Value = TempDT.Rows(0).Item("Name")
            End If
        Next



    End Sub

    Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
        Me.Size = New Size(800, 600)
        Me.Location = New Point(10, 10)

    End Sub

    Private Sub ShowFavesChB_CheckedChanged(sender As Object, e As EventArgs) Handles ShowFavesChB.CheckedChanged
        If ShowFavesChB.Checked = True Then
            My.Settings.ShowFaves = True
            CListDGV.Columns("Favorite").Visible = True
        Else
            My.Settings.ShowFaves = False
            CListDGV.Columns("Favorite").Visible = False
        End If
        My.Settings.Save()
    End Sub

    Private Sub CustomLists_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        ShowFavesChB.Checked = My.Settings.ShowFaves
    End Sub

    Private Sub DefPic1_MouseClick(sender As Object, e As MouseEventArgs) Handles DefPic6.MouseClick, DefPic5.MouseClick, DefPic4.MouseClick, DefPic3.MouseClick, DefPic2.MouseClick, DefPic1.MouseClick

        If e.Button = Windows.Forms.MouseButtons.Left Then
            Dim Prev As New PictureViewer
            Select Case sender.name
                Case "DefPic1"
                    Prev.Image = SafeImageFromFile(IconsPath & "ListsMain.png")
                Case "DefPic2"
                    Prev.Image = SafeImageFromFile(IconsPath & "ListFolder.png")
                Case "DefPic3"
                    Prev.Image = SafeImageFromFile(IconsPath & "ListGames.png")
                Case "DefPic4"
                    Prev.Image = SafeImageFromFile(IconsPath & "ListLoad.png")
                Case "DefPic5"
                    Prev.Image = SafeImageFromFile(IconsPath & "ListView.png")
                Case "DefPic6"
                    Prev.Image = SafeImageFromFile(IconsPath & "ListWWW.png")
            End Select
            Prev.Show()
        ElseIf e.Button = Windows.Forms.MouseButtons.Right Then
            With OFD1
                .Title = "Please select the Default Image for this Item"
                .Filter = "PNG|*.png|JPG|*.jpg"
                Try
                    .InitialDirectory = Path.GetDirectoryName(IconsPath)
                Catch
                    .InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
                End Try
            End With
            If OFD1.ShowDialog = Windows.Forms.DialogResult.OK Then
                Select Case sender.name
                    Case "DefPic1"
                        Dim img As String = IconsPath & "ListsMain.png"
                        If String.Compare(img, OFD1.FileName, True) <> 0 Then
                            File.Copy(OFD1.FileName, img, True)
                            sender.image = SafeImageFromFile(OFD1.FileName)
                        End If
                    Case "DefPic2"
                        Dim img As String = IconsPath & "ListFolder.png"
                        If String.Compare(img, OFD1.FileName, True) <> 0 Then
                            File.Copy(OFD1.FileName, img, True)
                            sender.image = SafeImageFromFile(OFD1.FileName)
                        End If
                    Case "DefPic3"
                        Dim img As String = IconsPath & "ListGames.png"
                        If String.Compare(img, OFD1.FileName, True) <> 0 Then
                            File.Copy(OFD1.FileName, img, True)
                            sender.image = SafeImageFromFile(OFD1.FileName)
                        End If
                    Case "DefPic4"
                        Dim img As String = IconsPath & "ListLoad.png"
                        If String.Compare(img, OFD1.FileName, True) <> 0 Then
                            File.Copy(OFD1.FileName, img, True)
                            sender.image = SafeImageFromFile(OFD1.FileName)
                        End If
                    Case "DefPic5"
                        Dim img As String = IconsPath & "ListView.png"
                        If String.Compare(img, OFD1.FileName, True) <> 0 Then
                            File.Copy(OFD1.FileName, img, True)
                            sender.image = SafeImageFromFile(OFD1.FileName)
                        End If
                    Case "DefPic6"
                        Dim img As String = IconsPath & "ListWWW.png"
                        If String.Compare(img, OFD1.FileName, True) <> 0 Then
                            File.Copy(OFD1.FileName, img, True)
                            sender.image = SafeImageFromFile(OFD1.FileName)
                        End If
                End Select



                ImagePathTextBox.Text = OFD1.FileName
                ListItemImgPB.Image = SafeImageFromFile(OFD1.FileName)
                ListItemImgPB.Tag = OFD1.FileName

            End If


            'DefPic1.Image = SafeImageFromFile(IconsPath & "ListsMain.png")
            'DefPic2.Image = SafeImageFromFile(IconsPath & "ListFolder.png")
            'DefPic3.Image = SafeImageFromFile(IconsPath & "ListGames.png")
            'DefPic4.Image = SafeImageFromFile(IconsPath & "ListLoad.png")
            'DefPic5.Image = SafeImageFromFile(IconsPath & "ListView.png")
            'DefPic6.Image = SafeImageFromFile(IconsPath & "ListWWW.png")
        End If


    End Sub

    Private Sub ListsDGV_CellClick(sender As Object, e As DataGridViewCellEventArgs) Handles ListsDGV.CellClick
        If e.RowIndex < 0 Or e.ColumnIndex < 0 Then Return

        Dim ListID As Integer = ListsDGV.Rows(e.RowIndex).Cells("ID").Value
        _status.echo("ListsDGV List ID: " & ListID)

        Dim pos As Integer = ListBindingSource.Find("ID", ListID)
        ListBindingSource.Position = pos
    End Sub

   
    Private Sub DelListsBT_Click(sender As Object, e As EventArgs) Handles DelListsBT.Click

        Process.Start(Application.StartupPath & "\GameExMenuEditor.exe")

        ' =====================================================================================================
        ' YET ANOTHER REDUNDANT IDEA!
        'Delete any lists
        'Consturct Datatable
        '_status.echo("==================================================")
        '_status.echo("==================================================")

        'Dim GECMenuIni As New IniFile
        'GECMenuIni.Load(Application.StartupPath() & "\CONFIG\CustomMenu.ini")
        'Dim Sec As IniFile.IniSection = GECMenuIni.GetSection(CustMenuSecs.Item(RootCB.Text))
        'If Sec Is Nothing Then Return
        'If Sec.GetKey("CUSTOMLIST") Is Nothing Then
        '    MsgBox("This Custom GameEx Menu does not contain any Custom Lists.", MsgBoxStyle.Exclamation, "CustomLists")
        '    Return
        'End If

        ''Does contain Custom List.

        'CListDS.Tables("OpsDT").Clear()
        'Dim nrow As DataRow = CListDS.Tables("OpsDT").NewRow
        'For Each key As IniFile.IniSection.IniKey In Sec.Keys
        '    _status.echo("Key, Value: " & key.Name & ", " & key.Value)
        '    Dim values() As String = key.Value.Split(",")

        '    If values.Length > 3 Then

        '    End If

        '    nrow("Type")
        'Next
        'First present all folders to user and get List to delete:
        ' =====================================================================================================

    End Sub

    Private Sub RootCB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles RootCB.SelectedIndexChanged

    End Sub

    Private Sub URLCB_SelectedIndexChanged(sender As Object, e As EventArgs) Handles URLCB.SelectedIndexChanged
        URLTextBox.Text = URLPairs(URLCB.Text)
    End Sub

    Private Sub URLTextBox_TextChanged(sender As Object, e As EventArgs) Handles URLTextBox.TextChanged
        '  URLCB.ValueMember = URLTextBox.Text
    End Sub

    Private Sub ListBindingSource_CurrentChanged(sender As Object, e As EventArgs) Handles ListBindingSource.CurrentChanged
        _status.echo("Record changed")
        If URLTextBox.Text <> "" And URLTextBox.Text IsNot Nothing Then
            _status.echo("Changing CB to: " & URLTextBox.Text)
            URLCB.SelectedIndex = URLCB.FindString(URLTextBox.Text)
        Else
            URLCB.SelectedIndex = -1
        End If
    End Sub

    Private Sub RestDefsBT_Click(sender As Object, e As EventArgs) Handles RestDefsBT.Click
        Dim DefImgs As New List(Of String) From {"ListFolder", "ListGames", "ListLoad", "ListsMain",
                                                         "ListView", "ListWWW"}
        IconsPath = GEThemePath & "LOGOS\"  ' IMPORTANT GLOBAL - DO NOT ERASE
        _log.echo("Checking Theme folder has needed images.")
        _log.echo("Folder: " & IconsPath)
        For Each filename As String In DefImgs
            Select Case filename
                Case "ListFolder"
                    My.Resources.ListFolder.Save(IconsPath & filename & ".png")
                Case "ListGames"
                    My.Resources.ListGames.Save(IconsPath & filename & ".png")
                Case "ListLoad"
                    My.Resources.ListLoad.Save(IconsPath & filename & ".png")
                Case "ListsMain"
                    My.Resources.ListsMain.Save(IconsPath & filename & ".png")
                Case "ListView"
                    My.Resources.ListView.Save(IconsPath & filename & ".png")
                Case "ListWWW"
                    My.Resources.ListWWW.Save(IconsPath & filename & ".png")
            End Select
        Next

        DefPic1.Image = SafeImageFromFile(IconsPath & "ListsMain.png")
        DefPic2.Image = SafeImageFromFile(IconsPath & "ListFolder.png")
        DefPic3.Image = SafeImageFromFile(IconsPath & "ListGames.png")
        DefPic4.Image = SafeImageFromFile(IconsPath & "ListLoad.png")
        DefPic5.Image = SafeImageFromFile(IconsPath & "ListView.png")
        DefPic6.Image = SafeImageFromFile(IconsPath & "ListWWW.png")

    End Sub
End Class

